package com.example.baseweb.service.impl;

import com.example.baseweb.common.PageResponse;
import com.example.baseweb.entity.OrderInfo;
import com.example.baseweb.entity.OrderDetail;
import com.example.baseweb.dto.OrderDetailDTO;
import com.example.baseweb.repository.OrderInfoRepository;
import com.example.baseweb.repository.OrderDetailRepository;
import com.example.baseweb.service.OrderService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import javax.persistence.criteria.Predicate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

@Service
public class OrderServiceImpl implements OrderService {
    
    @Autowired
    private OrderInfoRepository orderInfoRepository;
    
    @Autowired
    private OrderDetailRepository orderDetailRepository;
    
    @Override
    public OrderInfo getOrderById(Long id) {
        return orderInfoRepository.findById(id).orElse(null);
    }
    
    @Override
    public OrderDetailDTO getOrderDetail(Long orderId) {
        OrderInfo orderInfo = getOrderById(orderId);
        List<OrderDetail> orderDetails = getOrderDetails(orderId);
        return new OrderDetailDTO(orderInfo, orderDetails);
    }
    
    @Override
    @Transactional
    public OrderInfo updateOrderStatus(Long orderId, String status) {
        OrderInfo order = getOrderById(orderId);
        if (order != null) {
            order.setStatus(status);
            if ("PAID".equals(status)) {
                order.setPaymentTime(LocalDateTime.now());
                order.setPaymentMethod("WECHAT");
            }
            order.setUpdateTime(LocalDateTime.now());
            return orderInfoRepository.save(order);
        }
        return null;
    }
    
    @Override
    public List<OrderDetail> getOrderDetails(Long orderId) {
        return orderDetailRepository.findByOrderIdOrderByCreateTimeAsc(orderId);
    }
    
    @Override
    @Transactional
    public OrderInfo refundOrder(String orderNo) {
        OrderInfo order = orderInfoRepository.findByOrderNo(orderNo);
        if (order != null) {
            order.setStatus("REFUNDED");
            order.setUpdateTime(LocalDateTime.now());
            return orderInfoRepository.save(order);
        }
        return null;
    }
    
    @Override
    public PageResponse<OrderInfo> getOrderPage(int page, int size, String userName, String status) {
        Pageable pageable = PageRequest.of(page - 1, size);
        
        Specification<OrderInfo> spec = (root, query, criteriaBuilder) -> {
            List<Predicate> predicates = new ArrayList<>();
            
            if (StringUtils.hasText(userName)) {
                predicates.add(criteriaBuilder.like(root.get("userName"), "%" + userName + "%"));
            }
            
            if (StringUtils.hasText(status)) {
                predicates.add(criteriaBuilder.equal(root.get("status"), status));
            }
            
            return criteriaBuilder.and(predicates.toArray(new Predicate[0]));
        };
        
        Page<OrderInfo> orderPage = orderInfoRepository.findAll(spec, pageable);
        return PageResponse.of(orderPage.getContent(), orderPage.getTotalElements(), size, page);
    }
} 